#include "pack.h"

Pack::Pack()
{

}

void Pack::setType(Type type)
{
    this->type = type;
}

void Pack::setBack(Back back)
{
    this->back = back;
}

void Pack::setSize(int size)
{
    pack_size = size;
}

int Pack::size()
{
    return pack_size;
}

Type Pack::getType()const
{
    return type;
}

Back Pack::getBack()const
{
    return back;
}

void Pack::append(const QString &val)
{
    const char* p = val.toStdString().data();
    short len = strlen(p); // strlen ( char*)
    *(short*)(buf+used) = len;
    used += 2;

    memcpy(buf+used,p,len);
    used += len;

    pack_size = 12 + used;
}

void Pack::append(const char *p, int size)
{
    memset(buf,0,4096);
    memcpy(buf,p,size);
    pack_size = 12 + size;
}

QStringList Pack::readAll()const
{
    QStringList list;
    int readed_size = 0;// 准备一个记录已读多少自己的数据，方便指针偏移，跳过已读部分
    while(1){
        short size = *(short*)(buf+readed_size);
        if(size == 0){break;}
        readed_size += 2;

        char temp[size + 1];
        memset(temp,0,size+1);
        memcpy(temp,buf+readed_size,size);
        readed_size += size;

        QString str = QString::fromStdString(temp);
        list << str;
    }
    return list;
}

QByteArray Pack::readAll(int size)
{
    //QByteArray arr(buf); // arr {char* p} 构造函数拷贝的数据，只会从头拷贝到第一个结束符，非常容易出现数据不全的情况
    //return arr;
    return QByteArray::fromRawData(buf,size);
}

void Pack::readAll(char *buf, int size) const
{
    memcpy(buf, this->buf, size); // 拷贝指定大小的数据到外部buf
}

Pack &Pack::operator<<(const QString &val)
{
    append(val);
    return *this;
}

void Pack::operator>>(QTcpSocket *client)
{
    client->write((char*)this,pack_size);
}

void Pack::clear()
{
    // 重置Pack对象的状态
    type = static_cast<Type>(0);
    back = static_cast<Back>(0);
    pack_size = 0;
    used = 0;
    memset(buf, 0, sizeof(buf));
}
QByteArray Pack::packData() const
{
    QByteArray data;
    // 先写入包大小（4字节）
    data.append((char*)&pack_size, 4);
    // 写入类型（假设Type为4字节）
    data.append((char*)&type, 4);
    // 写入返回状态（假设Back为4字节）
    data.append((char*)&back, 4);
    // 写入实际数据
    data.append(buf, used);
    return data;
}
